/***********************************************************************************
 * 文件名： mcu_uart.h
 * 作者： 刘言
 * 版本： 1
 * 说明：
 *      中断入口统一定义在 isr.c 中。
 * 修改记录：
 * 	2023/4/21: 初版。 刘言。
***********************************************************************************/
#ifndef _MCU_UART_H_
#define _MCU_UART_H_

#ifdef __cplusplus
 extern "C" {
#endif

#include "mcu.h"
#include "components/soft_fifo/soft_fifo.h"

// 精简 UART_HandleTypeDef 仅保留 Instance，便于兼容HAL的一些操作接口
typedef struct __UART_HandleLite
{
  USART_TypeDef            *Instance;                /*!< UART registers base address        */
} UART_HandleLite;

// uart 类
typedef struct _uart_t
{
    u8 * TxBuff;
    SoftFifo * TxFifo;
    u8 * RxBuff;
    SoftFifo * RxFifo;
    u16 TxBuffSize;
    u16 RxBuffSize;
    bool Sending;       // true: 正在发送（发送缓存中有数据）
    bool IsOpen;        // true: 开启
    UART_HandleLite Handle;   // HAL UART 实例(已精简，仅保留了寄存器实例指针)
}uart_t;

extern uart_t _UART_USART1_NAME;
extern uart_t _UART_USART2_NAME;
extern uart_t _UART_USART3_NAME;
extern uart_t _UART_UART4_NAME;
extern uart_t _UART_UART5_NAME;
extern uart_t _UART_UART6_NAME;
extern uart_t _UART_UART7_NAME;

/**
 * 初始化指定UART，将会允许外设中断（未开启NVIC，使用 Nvic_Enable 使能）。
 * 时钟通过调用 Mcu_Init 统一开启,IO口分配与配置不在这里初始化。
 * @param uart UART对象指针，在配置文件中定义的各个UART名称
 * @param baud 波特率
*/
void Uart_Init(uart_t *uart, u32 baud);

/**
 * 写入(发送)一个字节
 * 如果缓存满了将会阻塞直到写入成功。
 * @param uart UART对象指针，在配置文件中定义的各个UART名称
 * @param c 一个字节的数据、一个字符
*/
void Uart_WriteByte(uart_t *uart, u8 c);

/**
 * 写入（发送）多个字节
 * 如果缓存满了将会阻塞直到写入成功。
 * @param uart UART对象指针，在配置文件中定义的各个UART名称
 * @param dat 要发的数据指针
 * @param size 要发的数据长度（字节数）
*/
void Uart_Write(uart_t *uart, const u8 *dat, size_t size);

/**
 * 从接收缓存中读取一个字节。
 * 如果没有接收缓存，将直接返回接收寄存器中的数据（即最后收到的一个字节）。
 * @param uart UART对象指针，在配置文件中定义的各个UART名称
 * @return 读出的字节数据，-1表示缓存是空的，未读出任何数据。
*/
int Uart_ReadByte(uart_t *uart);

/**
 * 从接收缓存中拷贝数据。
 * 如果没有接收缓存，将不进行任何操作并始终返回0，此种情况请使用 Uart_ReadByte 来直接读取寄存器。
 * @param uart UART对象指针，在配置文件中定义的各个UART名称。
 * @param buff 用于存放数据的缓存指针
 * @param cont 本次读取的最大数据长度（字节数）
 * @return 实际读取的长度（字节数）。
*/
int Uart_Read(uart_t *uart, u8 *buff, size_t cont);


void Uart_SetBaud(uart_t *this, u32 baud);



#ifdef __cplusplus
}
#endif

#endif

